package com.ganzalang.gmall.designpatterns.factory.methodfactory;

import lombok.extern.slf4j.Slf4j;

/**
 * @description: 使用工厂方法
 * @author: ganzalang
 */
@Slf4j
public class MethodFactoryPatternDemo {

    /**
     * 工厂方法是一个工厂只负责创建一种bean
     * 简单工厂是一个工厂可以创建多种bean
     * @param args
     */
    public static void main(String[] args) {
        Product productA = ProductAFactory.getInstance().create();
        Product productB = ProductBFactory.getInstance().create();
        Product productC = ProductBFactory.getInstance().create();
        productA.execute();
        productB.execute();
        productC.execute();
    }

    public interface Product {
        void execute();
    }

    public interface ProductFactory {
        Product create();
    }

    public static class ProductA implements Product {

        @Override
        public void execute() {
            log.info("执行商品A的方法");
        }
    }

    public static class ProductB implements Product {

        @Override
        public void execute() {
            log.info("执行商品B的方法");
        }
    }

    public static class ProductC implements Product {

        @Override
        public void execute() {
            log.info("执行商品C的方法");
        }
    }


    public static abstract class AbstractProductFactory implements ProductFactory {

        @Override
        public Product create() {
            commonCreate();
            return specificCreate();
        }

        private void commonCreate() {
            log.info("公共创建方法");
        };

        protected abstract Product specificCreate();
    }

    public static class ProductAFactory extends AbstractProductFactory {

        private static final ProductAFactory productAFactory = new ProductAFactory();

        private ProductAFactory() {
        }

        public static ProductAFactory getInstance(){
            return productAFactory;
        }

        @Override
        public Product specificCreate() {
            log.info("创建A的特殊方法");
            return new ProductA();
        }
    }

    public static class ProductBFactory extends AbstractProductFactory {

        private static final ProductBFactory productBFactory = new ProductBFactory();

        public ProductBFactory() {
        }

        public static ProductBFactory getInstance() {
            return productBFactory;
        }
        @Override
        public Product specificCreate() {
            log.info("创建B的特殊方法");
            return new ProductB();
        }
    }

    public static class ProductCFactory extends AbstractProductFactory {
        private static final ProductCFactory productCFactory = new ProductCFactory();

        public ProductCFactory() {
        }

        public static ProductCFactory getInstance() {
            return productCFactory;
        }
        @Override
        protected Product specificCreate() {
            log.info("创建C的特殊方法");
            return new ProductC();
        }
    }
}
